package com.hmy.finance.common.easyexcel;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.hmy.finance.common.easyexcel.pojo.exportbeans.ExportDemoData;
import com.hmy.finance.common.easyexcel.pojo.exportbeans.ExportSingleData;
import com.hmy.finance.common.easyexcel.pojo.exportbeans.ExportSingleSheetBaseContext;
import com.hmy.finance.common.easyexcel.pojo.importbeans.ImportSingleData;
import com.hmy.finance.common.easyexcel.pojo.readlistener.AbstractReadListener;
import com.hmy.finance.common.oss.OssStsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.MalformedURLException;
import java.util.Collections;
import java.util.List;
import java.util.Objects;


@Slf4j
@Component
public class SimpleExcelHandler<T extends ImportSingleData> implements ExcelHandlerInterface<T, ExportSingleSheetBaseContext<List<? extends ExportSingleData>>> {

    @Autowired
    private OssStsUtil ossStsUtil;

    @Override
    public List<T> excelImportHandler(String ossFileUrl, Class<T> targetClass, AbstractReadListener listener) throws MalformedURLException {
        /*逻辑测试:从本地拿到文件*/
//        File file = new File("/Users/weijunfei/Desktop/ex/file.xlsx");
//        FileInputStream fileInputStream;
//        try {
//            fileInputStream = new FileInputStream(file);
//        } catch (FileNotFoundException e) {
//            throw new RuntimeException(e);
//        }
        /*1.从oss获取文件;*/
        InputStream inputStream = ossStsUtil.downloadFile(ossFileUrl);

        /*2.根据文件内容解析;*/
        //DefaultReadListener<T> listener = new DefaultReadListener<>();
        ExcelReader excelReader = EasyExcelFactory.read(inputStream, targetClass, listener).build();
        ReadSheet readSheet = EasyExcelFactory.readSheet(0).build();
        excelReader.read(readSheet);
        excelReader.finish();
        /* 3.封装返回对象;*/
        return listener.getTotalDataList();
    }


    @Override
    public String excelExportHandler(ExportSingleSheetBaseContext<List<? extends ExportSingleData>> writeObj) {
        /*step1.参数校验*/
        if (Objects.isNull(writeObj) || CollectionUtil.isEmpty(writeObj.getData())) {
            throw new RuntimeException("导出数据不能为空");
        }
        if (Objects.isNull(writeObj.getFileName())) {
            throw new RuntimeException("导出数据文件名称不能为空");
        }

        String ossUrl;
        /*step2.根据模板将传入的对象写入Excel对象*/
        File file = new File(writeObj.getFileName() + ".xlsx");//只导出xlsx格式
        FileOutputStream fileOutputStream;
        try {
            fileOutputStream = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }

        Integer sheetNo = Objects.isNull(writeObj.getSheetNo()) ? 0 : writeObj.getSheetNo();
        String sheetName = Objects.isNull(writeObj.getSheetName()) ? "sheet" + sheetNo + 1 : writeObj.getSheetName();

        ExcelWriterBuilder excelWriterBuilder = EasyExcel.write(fileOutputStream).excelType(ExcelTypeEnum.XLSX);
        ExcelWriterSheetBuilder excelWriterSheetBuilder;
        if (CollectionUtil.isEmpty(writeObj.getHeads())) {
            /*如果不主动设置head聚合配置，则默认使用ExportData的注解值:@ExcelProperty.value*/
            excelWriterSheetBuilder = excelWriterBuilder
                    .head(writeObj.getClazz())
                    .sheet(sheetNo, sheetName);
        } else {
            /*如果主动设置head聚合配置，使用聚合配置*/
            excelWriterSheetBuilder = excelWriterBuilder
                    .head(writeObj.getHeads())
                    .sheet(sheetNo, sheetName);
        }
        excelWriterSheetBuilder.doWrite(writeObj.getData());

        /*step3.生成Excel文件流*/
        FileInputStream fileInputStream;
        try {
            fileInputStream = new FileInputStream(file);
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }

        /* 测试:写入本地文件系统*/
//        try {
//            FileOutputStream fos = new FileOutputStream("/Users/weijunfei/Desktop/ex/file.xlsx");
//            byte[] buffer = new byte[1024];
//            int bytesRead;
//            while ((bytesRead = fileInputStream.read(buffer)) != -1) {
//                fos.write(buffer, 0, bytesRead);
//            }
//        } catch (IOException e) {
//            e.printStackTrace();
//        }

        /*step5.上传oss,完成后删除本地文件*/
        ossUrl = ossStsUtil.uploadByStream(fileInputStream, writeObj.getFileName() + ".xlsx");
        file.delete();

        int questionMarkIndex = ossUrl.indexOf("?");
        // 如果找到了问号，则截取问号之前的部分；否则，返回原始字符串
        ossUrl = questionMarkIndex != -1 ? ossUrl.substring(0, questionMarkIndex) : ossUrl;
        return ossUrl;
    }

}
